#include "Http.h"
#include<stdio.h>
#include<Winsock2.h>
#include<string.h>
#include<shellapi.h>

#pragma comment(lib,"ws2_32.lib")

#define HTTP_PORT 80

Http::Http(std::string host,std::string serverid,std::string account, std::string password)
{
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
	{
		printf("%s","WSAStartup failed");
	}
	const char *hname=host.c_str();
	char *page="/";
	char *poststr="";
	struct hostent *hptr;
	if ((hptr=gethostbyname(hname))==NULL)
	{
		printf("%s","error");
	}
	else
	{
		printf("Connect to : %s\n",hptr->h_name);
	}
	unsigned long ip;
	ip=inet_addr(inet_ntoa(*(struct in_addr *)*hptr->h_addr_list));
	SOCKET s=socket(AF_INET,SOCK_STREAM,0);
	struct sockaddr_in serveraddr;
	ZeroMemory(&serveraddr,sizeof(serveraddr));
	serveraddr.sin_family=AF_INET;
	serveraddr.sin_port=htons((short)HTTP_PORT);
	serveraddr.sin_addr.s_addr=ip;
	int flag=connect(s,(sockaddr*)&serveraddr,sizeof(sockaddr_in));
	if (flag)
	{
		printf("failed to connect to %s\n",host.c_str());
		return;
	}

	char sendline[4097]={0};
	_snprintf_s(sendline,1000,"GET / HTTP/1.1\r\nHost: %s\r\n\r\n",host.c_str());
	size_t msglen=strlen(sendline);
	if (!send(s,sendline,(int)msglen,0))
	{
		printf("%s\n","send msg failed");
		closesocket(s);
		return;
	}
	char buffer[128000]={0};
	printf("Received : %dB\n",recv(s,buffer,128000,0));
	if (strlen(buffer)<strlen("Set-Cookie"))
	{
		closesocket(s);
		return;
	}
	char cookie[1000]={0};
	strcpy(cookie,GetValueByKey(buffer,"Set-Cookie: ",";"));
	char form_submit_key_time[11]={0};
	strcpy(form_submit_key_time,GetValueByKey(buffer,"\"form_submit_key_time\" value=\"","\""));
	char form_submit_key_v1[33]={0};
	strcpy(form_submit_key_v1,GetValueByKey(buffer,"\"form_submit_key_v1\" value=\"","\""));
	char form_submit_key_v2[33]={0};
	strcpy(form_submit_key_v2,GetValueByKey(buffer,"\"form_submit_key_v2\" value=\"","\""));
	char fik1[35]={0};
	strcpy(fik1,GetValueByKey(buffer,"\"fik1\" value=\"","\""));
	char fik2[35]={0};
	strcpy(fik2,GetValueByKey(buffer,"\"fik2\" value=\"","\""));
	int length=324+account.length()+password.length()+19;
	_snprintf_s(sendline,1500,"POST /user/login.phtml HTTP/1.1\r\nHost: %s\r\nConnection: keep-alive\r\nContent-Length: %d\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nOrigin: http://%s\r\nUser-Agent: Mozilla/5.0 (Windows NT 5.1; rv:19.0) Gecko/20100101 Firefox/19.0\r\nContent-Type: application/x-www-form-urlencoded\r\nReferer: http://%s/game/rxsg2.phtml\r\nAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\nAccept-Charset: GBK,utf-8;q=0.7,*;q=0.3\r\nCookie:  Hm_lvt_8c13a699eb6a7579b36b376356087e10=1362820884,1362821249; Hm_lpvt_8c13a699eb6a7579b36b376356087e10=%s\r\n\r\nact=submit&form_submit_key_time=%s&form_submit_key_v1=%s&form_submit_key_v2=%s&fik1=%s&fik2=%s&url=%%2Fgame%%2Frxsg2.phtml&%s=%s&%s=%s&myaction=1&button=",host.c_str(),length,host.c_str(),host.c_str(),form_submit_key_time,form_submit_key_time,form_submit_key_v1,form_submit_key_v2,fik1,fik2,fik1,account.c_str(),fik2,password.c_str());
	msglen=strlen(sendline);
	if (!send(s,sendline,(int)msglen,0))
	{
		printf("%s\n","send msg failed");
		closesocket(s);
		return;
	}
	memset(buffer,0,128000);
	printf("Received : %dB\n",recv(s,buffer,128000,0));
	if (strlen(buffer)<strlen("Set-Cookie"))
	{
		closesocket(s);
		return;
	}
	char cookie2[1000]={0};
	strcpy(cookie2,GetCookie(buffer));
	_snprintf_s(sendline,1500,"GET /server/login/%s.phtml HTTP/1.1\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Windows NT 5.1; rv:19.0) Gecko/20100101 Firefox/19.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Charset: GBK,utf-8;q=0.7,*;q=0.3\r\nAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\nReferer: http://%s/game/rxsg2.phtml\r\nCookie: Hm_lvt_8c13a699eb6a7579b36b376356087e10=1361625967,1361687588,1361720342,1361796680; Hm_lpvt_8c13a699eb6a7579b36b376356087e10=%s; %s\r\nConnection: keep-alive\r\n\r\n",serverid.c_str(),host.c_str(),host.c_str(),form_submit_key_time,cookie2);
	msglen=strlen(sendline);
	if (!send(s,sendline,(int)msglen,0))
	{
		printf("%s\n","send msg failed");
		closesocket(s);
		return;
	}
	memset(buffer,0,128000);
	printf("Received : %dB\n",recv(s,buffer,128000,0));
	if (strlen(buffer)<strlen("Set-Cookie"))
	{
		closesocket(s);
		return;
	}
	char url[300]={0};
	strcpy(url,"http");
	strcpy(url+4,GetValueByKey(buffer,"<frame src=\"http","\""));
	ShellExecuteA(NULL,"open",url,NULL,NULL,SW_SHOWNORMAL);
	closesocket(s);
}

char* Http::GetValueByKey(char text[],char *startKey,char *endKey)
{
	static char ret[1000]={0};
	size_t txtlen=strlen(text);
	size_t startKeylen=strlen(startKey);
	size_t endKeylen=strlen(endKey);
	int start=-1;
	int end=-1;
	for (int i=0;(size_t)i<txtlen-startKeylen-endKeylen;i++)
	{
		char tmp[1000]={0};
		strncpy_s(tmp,startKeylen+1,text+i,startKeylen);
		if (!strcmp(tmp,startKey))
		{
			start=i;
			i=start+startKeylen+1;
			continue;
		}
		if (i>=txtlen-startKeylen-endKeylen)
		{
			break;
		}
		strncpy_s(tmp,endKeylen+1,text+i,endKeylen);
		if (start>=0 && !strcmp(tmp,endKey))
		{
			end=i;
			break;
		}
	}
	if (start>=0 && end>0 && start<end)
	{
		strncpy_s(ret,end-start-startKeylen+1,text+start+startKeylen,end-start-startKeylen);
	}
	return ret;
}

char* Http::GetCookie(char text[])
{
	size_t textlen=strlen(text);
	size_t keylen=strlen("Set-Cookie:");
	int flag=0;
	int start[2]={-1};
	int end[2]={-1};
	for (int i=0;i<textlen-keylen;i++)
	{
		char tmp[1000]={0};
		strncpy_s(tmp,keylen+1,text+i,keylen);
		if (!strcmp(tmp,"Set-Cookie:"))
		{
			flag++;
			if (flag>1 && flag<4)
			{
				start[flag-2]=i+keylen+1;
				while(true)
				{
					if (text[i]!=';')
					{
						i++;
					}
					else
					{
						break;
					}
				}
				if (i<textlen)
				{
					end[flag-2]=i+1;
				}

			}
		}
	}
	static char ret[1000]={0};
	strncpy_s(ret,end[0]-start[0]+1,text+start[0],end[0]-start[0]);
	strncpy_s(ret+end[0]-start[0],end[1]-start[1]+1,text+start[1],end[1]-start[1]);
	return ret;
}